<?php
/* SVN FILE: $Id: app_controller.php 4407 2007-02-02 10:39:45Z phpnut $ */
/**
 * Short description for file.
 *
 * This file is application-wide controller file. You can put all
 * application-wide controller-related methods here.
 *
 * PHP versions 4 and 5
 *
 * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
 * Copyright 2005-2007, Cake Software Foundation, Inc.
 *					1785 E. Sahara Avenue, Suite 490-204
 *					Las Vegas, Nevada 89104
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @copyright		Copyright 2005-2007, Cake Software Foundation, Inc.
 * @link			http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
 * @package			cake
 * @subpackage		cake.app
 * @since			CakePHP(tm) v 0.2.9
 * @version			$Revision: 4407 $
 * @modifiedby		$LastChangedBy: phpnut $
 * @lastmodified	$Date: 2007-02-02 04:39:45 -0600 (Fri, 02 Feb 2007) $
 * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
 */
 
 /**
  * Include the core library Sanitize
  * a class you can use to rid user-submitted data of malicious attacks and other unwanted data
  */
 uses('sanitize');
 
/**
 * Short description for class.
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @package		cake
 * @subpackage	cake.app
 */
class AppController extends Controller {
	
	/**
	 * Use this variable to have every controller load these helpers into its views.
	 */
	var $helpers = array('Html', 'Form' , 'Error', 'Ajax', 'Javascript', 'Pagination');
	
	/**
	 * $components variable is used to load up components you will need:
	 */
	//var $components = array('Security', 'RequestHandler', 'Pagination');
	var $components = array('Security', 'RequestHandler', 'Pagination', 'Cookie', 'Report', 'DbTable');
	
	
	var $uses = array('TableStatus');
	/**
	 * 
	 */
	//var $uses = array('Sanitize');
	 
	/**
	 * Variable $transactional tells Cake whether or not to enable transactions for this model (i.e. begin/commit/rollback). Set to a boolean value.
	 */
	var $transactional = true;
	 
	/**
	 * Setting variable $autoRender to false will stop your actions from automatically rendering.
	 */
	 var $autoRender = true;
	
		
	/**
	 * beforeRender() Called after the controller action is run, but before the view is rendered
	 */ 
	function beforeRender() {
		
		header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); // // HTTP/1.1
		header("Pragma: no-cache");
		header("Expires: Mon, 17 Dec 2007 00:00:00 GMT"); // Date in the past
		
	} 
	
	/**
	 * use $beforeFilter, if you'd like a bit of code run every time an action is called (and before any of that action code runs).
	 */
	function beforeFilter() {
		
		// Set Timezone
		date_default_timezone_set("Asia/Calcutta");
		
	//	$this->checkCookies();
		$this->checkSession();
		$this->checkFileSystemPermission();
		$this->checkMalformedUrl();
	
		//$this->DbTable->setModel($this->TableStatus);
		$this->setAutoIncremetsForModelObjects();
		
	}
	
	function afterFilter() {
		
		$this->saveModelAutoIncrements();
		
	}
	
	function checkCookies() {
		
		if (isset($_COOKIE["cookies"])) {
			echo "cookies Enabled";
		} else {
			echo "cookies disabled";
		}
		
	}
	
	function cleanupData() {
		
		$this->checkJavaScript();
		$this->cleanUpFields();
		$this->sanitizeData();
		$this->checkForeignKeys();
		
	}
	
	/*
	function beforeRender(){
		if($this->action == 'index' || $this->action == 'view'){
			echo "<div style='text-align:left;'>";
			debug($this);
			echo "</div>";
		}
	}
	*/
	
	function checkJavaScript() {
		
		if (!array_key_exists('JavaScriptCheck', $this->data)) {
			$this->Session->setFlash('You must enable JavaScript in your Browser.', 'message_error');
			$this->redirect("/pages/no_javascript");
			exit();
		}
		
	}
	
	function checkMalformedUrl($modelClass = null) {
		
		if($modelClass == null) {
            $modelClass = $this->modelClass;
        }
		$urlMalformed = false;
		$cookieName = "Pagination";
		unset($cookieData);
		$this->Cookie->setpath($this->webroot);
		$cookieData = $this->Cookie->read($cookieName);
		if(isset($this->params['url']['sortByClass'])){
			if (!class_exists($this->params['url']['sortByClass'])) {
				$urlMalformed = true;
			} 
		} else if(isset($this->params['url']['sortBy'])){
			if(!$this->{$modelClass}->hasField($this->params['url']['sortBy'])){
				$urlMalformed = true;
			} 
		}
		if(isset($this->params['url']['direction'])){
			if(!($this->params['url']['direction'] == "ASC" || $this->params['url']['direction'] == "DESC")){
				$urlMalformed = true;
			}
		}
		if(isset($this->params['url']['page'])){
			if(!(is_numeric($this->params['url']['page']))){
				$urlMalformed = true;
			} else {
				$cookieData[$this->name]['page'] = $this->params['url']['page'];
			}
		} else {
			if(isset($cookieData[$this->name]['page'])){
				$this->Pagination->page = $cookieData[$this->name]['page'];
				$this->params['url']['page'] = $cookieData[$this->name]['page'];
			}
		}
		if(isset($this->params['url']['show'])){
			if(!(is_numeric($this->params['url']['show']))){
				$urlMalformed = true;
			} else {
				$cookieData[$this->name]['show'] = $this->params['url']['show'];
			}
		} else {
			if(isset($cookieData[$this->name]['show'])){
				$this->Pagination->show = $cookieData[$this->name]['show'];
				$this->params['url']['show'] = $cookieData[$this->name]['show'];
				/*
				if($this->Pagination->show !5)
					$this->Pagination->page = 1;
				*/
			} 
		}
			
		if($urlMalformed){
			$userInfo = $this->Session->read('User');
			$user_name = $userInfo['user_name']; 
			if(isset($_SERVER['REQUEST_URI'])){
				$badUrl = $_SERVER['REQUEST_URI']; 
			}
			// Write a log Entry
			$this->log(ERROR_BAD_REQUEST.", Bad Request, User:". $user_name . ", IP:".$this->RequestHandler->getClientIP().", Found malformed url '".$badUrl ."'.");
			$this->Session->setFlash('Bad Request.', 'message_error');
			if($this->RequestHandler->isAjax()){
				$this->redirect("/pages/ajax_error");
			} else {
				$this->redirect("/".$this->params['controller']);
			}
	        exit();
		}
		$this->Cookie->update($cookieName, $cookieData);
		
	}
	
	function setupPagination($modelClass = null) {
		if($modelClass == null) {
            $modelClass = $this->modelClass;
        }
		$page = (isset($this->params['url']['page']))? $this->params['url']['page']: 1; 
		$show = (isset($this->params['url']['show']))? $this->params['url']['show']: 6;
		$start = $show*($page-1)+1;
		if($start > $this->{$modelClass}->findCount()) {
			$start = 1;
		} 
		$this->set('count', $start);
		$criteria = NULL;
		$parameters = array();
		$settings = array('style' => "ajax");
		$this->{$modelClass}->recursive = 0;
       	return $this->Pagination->init($criteria, $parameters, $settings);
	}
	
	function checkRecordExistance($id=null, $modelClass = null) {
		if($modelClass == null) {
            $modelClass = $this->modelClass;
        }
		$fields[$modelClass.'.id'] = $id; 
		if(!$id || !$this->{$modelClass}->hasAny($fields)){
			$userInfo = $this->Session->read('User');
			$user_name = $userInfo['user_name'];
			if(isset($this->params['url']['url'])){
				$url = "/".$this->params['url']['url']; 
			} else if(isset($_SERVER['REQUEST_URI'])){
				$url = $_SERVER['REQUEST_URI']; 
			}
			// Write a log Entry
			$this->log(ERROR_NOT_FOUND.", Resource not found, User:". $user_name . ", IP:".$this->RequestHandler->getClientIP().", Resource url '".$url ."'.");
			$this->Session->setFlash('No such record exists.', 'message_error');
			$this->redirect("/".$this->params['controller']);
	        exit();
		}
	}
	
	function sanitizeData($modelClass = null) {
		if($modelClass == null) {
            $modelClass = $this->modelClass;
        }
		// Create a new Sanitize object:
		$Sanitize = new Sanitize();
		// From here, you can use Sanitize to clean your data
		// To clean array recursively
		//$Sanitize->cleanArray($this->data); 
		// $this->data used to handle POST data sent from HTML Helper forms to the controller.
		foreach($this->data[$modelClass] as $fieldName=>$fieldValue){
			if(!is_array($fieldValue)){
				// Strips the white space, images, and scripts from $fieldValue (using stripWhitespace(), stripImages(), and stripScripts()).
				$fieldValue = $this->RequestHandler->stripAll($fieldValue);
				// Strips whitespace from $fieldValue. 
				// $fieldValue = $this->RequestHandler->stripWhiteSpace($fieldValue);
				// Strips any HTML embedded images from $fieldValue.
				// $fieldValue = $this->RequestHandler->stripImages($fieldValue);
				// Strips any <script> and <style> related tags from $fieldValue.
				// $fieldValue = $this->RequestHandler->stripScripts($fieldValue);
				
				// Any HTML tag is removed.
				$fieldValue = strip_tags($fieldValue);
				
				// To remove leading/trailing white spaces
				$fieldValue = trim($fieldValue);
				
				// To escape from strings starting with '!' characters
				if (strlen($fieldValue) > 0) {
					while($fieldValue[0] == '!') {
						$fieldValue = substr($fieldValue, 1);
					}
				}
				// To escape SQL statements by adding slashes, depending on the system's current magic_quotes_gpc setting.
				$fieldValue = $Sanitize->sql($fieldValue);
				//$fieldValue = $Sanitize->html($fieldValue);
				$this->data[$modelClass][$fieldName] = $fieldValue;
			}
		}
	}
		
	function checkForeignKeys($modelClass = null) {
		if($modelClass == null) {
            $modelClass = $this->modelClass;
        }
		if(is_array($this->{$modelClass}->belongsTo) && count($this->{$modelClass}->belongsTo)){
			foreach($this->{$modelClass}->belongsTo as $relationArray){
				if($this->data[$modelClass][$relationArray['foreignKey']] == ''){
					$this->data[$modelClass][$relationArray['foreignKey']] = NULL;
				} else {
					unset($fields);
					$fields[$relationArray['className'].'.id'] = $this->data[$modelClass][$relationArray['foreignKey']];
					if(!($this->{$modelClass}->{$relationArray['className']}->hasAny($fields))){
						$this->data[$modelClass][$relationArray['foreignKey']] = NULL;
					} 
				}
			}
		}
	}
	
	
	
	function setAutoIncremetsForModelObjects() {

		$excludeModels = array("User", "Aro", "Aco", "ArosAco", "Pages");
		if (in_array($this->name, $excludeModels)) {
			return;
		}
		
		$this->DbTable->setModel($this->TableStatus);
		
		foreach ($this->modelNames as $modelName) {
			$this->{$modelName}->nextInsertId = $this->DbTable->getNextInsertId($modelName);
		}
		
	}
	
	function saveModelAutoIncrements() {
		
		$excludeModels = array("User", "Aro", "Aco", "ArosAco", "Pages");
		if (in_array($this->name, $excludeModels)) {
			return;
		}
		
		$this->DbTable->setModel($this->TableStatus);
		
		foreach ($this->modelNames as $modelName) {
			$maxId = $this->{$modelName}->find(null, 'MAX('.$modelName.'.id)');
			if (count($maxId)) {
				$lastId = $maxId[0]["MAX(`$modelName`.`id`)"];
			} else {
				$lastId = 0; 
			}
			$this->DbTable->updateTableStatus($modelName, $lastId);
		}

	}
	
	function checkSession() {
        // If the session info hasn't been set...
        if (!$this->Session->check('User')) {
            // Force the user to login
            $this->set('user', 'Guest');
			// Controller parameters are available at $this->params in your Cake controller
			// The most common usage of $this->params is to get access to information that has been handed to the controller via POST or GET operations.
			// $this->params['ajax'] stores '1' if the current layout is ajax, '0' if not.
			// $this->params['url'] stores the current URL requested, along with key-value pairs of get variables.
			if(isset($this->params['url']['url'])){
				$continue = $this->params['url']['url'];
				if($this->RequestHandler->isAjax()){
	            	$this->redirect('/ajax/users/session_timeout');
			        exit();
				}
				else{
	            	$this->redirect('/users/login?continue=/' . $continue);
		            exit();
				}
			} else {
				if($this->RequestHandler->isAjax()){
					$this->set('url', 'login');
	            	$this->redirect('/ajax/users/session_timeout');
			        exit();
				} else {
					$this->redirect('/users/login');
            		exit();
				}
			}
        } else { 
            $this->set('logged', true);
            $this->set('userInfo', $this->Session->read('User'));
		}

    }
	
	function checkAdminAccess() {
		$userInfo = $this->Session->read('User');
		$user_name = $userInfo['user_name']; 
		$user_admin = $userInfo['user_admin']; 
        if(!$user_admin) {
			// Write a log Entry
			$url = $this->params['url']['url'];
			$this->log(ERROR_ACCESS_DENIED." Access denied, User:". $user_name . ", IP:".$this->RequestHandler->getClientIP().", Attempt to access forbidden resource '".$url ."'.");
			$this->Session->setFlash('You are not authorised to perform this operaion.', 'message_error');
			$this->redirect('/pages/access_denied');
        }
	}
	
	function checkFileSystemPermission() {
		$cakeRoot = realpath(ROOT);
		if(!is_readable($cakeRoot) || !is_readable($cakeRoot)){
			$this->Session->setFlash('Please check access permission to cakePHP root folder.', 'message_error');
			$this->redirect('/pages/permission_error');
			exit(0);
		}
	}
	
	/**
	 * This function is an application-wide error handler
	 * When any unknown or unhandled error occurs in the application this function is called
	 * Function logs error number and description for troubleshooting purposes and redirects controll to a generic error page 
	 * @param int $errorNo Error number
	 * @param string $errorMsg Description of the error
	 */
	function showError($errorNo=null, $errorMsg=null, $logUrl=false) {
		if($errorNo == null) {
	    	$errorNo = 101;
	    }
		if($errorMsg == null) {
	    	$errorMsg = "Internal Error.";
	    }
		$userInfo = $this->Session->read('User');
		$user_name = $userInfo['user_name']; 
		// Write a log Entry
		if($logUrl){
			if(isset($_SERVER['REQUEST_URI'])){
				$url = $_SERVER['REQUEST_URI']; 
			} else {
				$url = $this->params['url']['url']; 
			}
			$this->log($errorNo.", User:".$user_name.", IP:".$this->RequestHandler->getClientIP().", Error details: ".$errorMsg.", URL: ".$url);
		} else {
			$this->log($errorNo.", User:".$user_name.", IP:".$this->RequestHandler->getClientIP().", Error details: ".$errorMsg);
		}
		$this->Session->setFlash($errorMsg, 'message_error');
		$this->redirect('/pages/generic_error?errorNo='.$errorNo);
		exit();
	}
	
	/**
	 * Function: reports()
	 * Action:   Build a dynamic report.
	 */
    function reports()
    {
        if (!empty($this->data)) 
        { 
            //Determine if user is pulling existing report or deleting report
            if(isset($this->params['form']['existing']))
            {
                if($this->params['form']['existing']=='Show')
                {
                    //Pull report
                    $this->Report->pull_report($this->data['Misc']['saved_reports']);
                }
                else if($this->params['form']['existing']=='Delete')
                {
                    //Delete report
                    $this->Report->delete_report($this->data['Misc']['saved_reports']);

                    //Return user to form
                    $this->Session->setFlash('Your report has been deleted.', 'message_ok');
					$this->redirect($this->name.'/'.$this->action);
					exit(0);
                }
            }
            else
            {
                //Filter out fields
                $this->Report->init_display($this->data);
                
                //Set sort parameter
                if(!isset($this->params['form']['order_by_primary'])) { $this->params['form']['order_by_primary']=NULL; }
                if(!isset($this->params['form']['order_by_secondary'])) { $this->params['form']['order_by_secondary']=NULL; }
                $this->Report->get_order_by($this->params['form']['order_by_primary'], $this->params['form']['order_by_secondary']);

                //Store report name
                if(!empty($this->params['form']['report_name']))
                {
                    $this->Report->save_report_name($this->params['form']['report_name']);
                }

                //Store report if save was executed
                if($this->params['form']['submit']=='Create And Save Report')
                {
                    if(empty($this->params['form']['report_name']))
                    {
                        //Return user to form
                        $this->flash('Must enter a report name when saving.','/'.$this->name.'/'.$this->action.'');
                    }
                    else
                    {
                        $this->Report->save_report();
                    }
                }
            }
            
            //Set report fields
            $this->set('report_fields', $this->Report->report_fields);

            //Set report name
            $this->set('report_name', $this->Report->report_name);

            //Allow search to go 2 associations deep
            $this->{$this->modelClass}->recursive = 2;

            //Set report data
            $this->set('report_data', $this->{$this->modelClass}->findAll(NULL,NULL,$this->Report->order_by));
            $this->render('../pages/reports');
        } 
        else
        {
            //Setup options for report component
            /*
                You can setup a level two association by doing the following:
                "VehicleDriver"=>"Employee" ie $models = Array ("Vehicle", "VehicleDriver"=>"Employee");
                Please note that all fields within a level two association cannot be sorted.
            */
            $models =    $this->models;

            //Set array of fields
            $this->set('report_form', $this->Report->init_form($models));
   
            //Set current controller
            $this->set('cur_controller', $this->name);

            //Pull all existing reports
            $this->set('existing_reports', $this->Report->existing_reports());
            $this->render('../pages/reports');
            
        }
    }
    
    function admin_help(){
    	$this->help();	
	}
	
    function help() {
		header("Content-Disposition: inline");
		$this->redirect('/files/docs/'.$this->name.'_User_Guide.html');
		//$this->redirect('/files/pdfs/'.$this->name.'User_Guide.pdf');
    	exit(0);
    }
	
	/**
	 * Before converting the data to YAML format, check data and do necessary replacements
	 *
	 * @param unknown_type $data
	 * @return unknown
	 */
    function prepareDataForYamlConversion($data) {
    	
    	foreach ($data as $index => $value) {
    		if (is_array($value)) {
    			if (count($value) == 0 ) {
    				// If the array is empty do not include this field in yaml data 
	    			unset($data[$index]);
    			} else {
	    			// Recursive check
    				$data[$index] = $this->prepareDataForYamlConversion($value);
    			}
    		} else 	{
    			/*
  				$value = preg_replace("/(&)([a-z])([a-z]+;)/i", '', $value);
  				$value = preg_replace("/[^A-Z0-9_-,;:]/i", '', $value);
  				$value = preg_replace("/\s+/i", '', $value);
				*/	
    			$value = trim($value);
    			if (empty($value)) {
    				// If the value is blank do not include this field in yaml data 
	    			unset($data[$index]);
    			} else {
	    			// Remove trailing commas
    				$value = (substr($value, -1) == ',') ? substr($value, 0, -1) : $value;
	    			// Replace commas with semi columns  
    				$data[$index] = str_replace(',', ';', $value); 
	    		}
    		}
    	}
    	return $data;
    	
    }
    
/**
 * Cleans up the date fields of current Model.
 * 
 * Overrides cleanUpFields() function of Controller class in controller.php
 *
 * @param string $modelName
 * @access public
 */
	function cleanUpFields($modelName = null) {
		if ($modelName == null) {
			$modelName = $this->modelClass;
		}

		foreach($this->{$modelName}->_tableInfo->value as $field) {
			if ('date' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
				$newDate = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
				$newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
				$newDate .= $this->params['data'][$modelName][$field['name'] . '_day'];
				unset($this->params['data'][$modelName][$field['name'] . '_year']);
				unset($this->params['data'][$modelName][$field['name'] . '_month']);
				unset($this->params['data'][$modelName][$field['name'] . '_day']);
				unset($this->params['data'][$modelName][$field['name'] . '_hour']);
				unset($this->params['data'][$modelName][$field['name'] . '_min']);
				unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
				$this->params['data'][$modelName][$field['name']] = $newDate;
				$this->data[$modelName][$field['name']] = $newDate;

			} elseif('datetime' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
				$hour = $this->params['data'][$modelName][$field['name'] . '_hour'];

				if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
					$hour = $hour + 12;
				}

				$newDate  = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
				$newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
				$newDate .= $this->params['data'][$modelName][$field['name'] . '_day'] . ' ';
			//	$newDate .= $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
				$newDate .= $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':' . $this->params['data'][$modelName][$field['name'] . '_sec'];
				unset($this->params['data'][$modelName][$field['name'] . '_year']);
				unset($this->params['data'][$modelName][$field['name'] . '_month']);
				unset($this->params['data'][$modelName][$field['name'] . '_day']);
				unset($this->params['data'][$modelName][$field['name'] . '_hour']);
				unset($this->params['data'][$modelName][$field['name'] . '_min']);
				unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
				$this->params['data'][$modelName][$field['name']] = $newDate;
				$this->data[$modelName][$field['name']] = $newDate;

			} elseif('time' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_hour'])) {
				$hour = $this->params['data'][$modelName][$field['name'] . '_hour'];

				if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
					$hour = $hour + 12;
				}

			//	$newDate = $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
				$newDate = $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':' . $this->params['data'][$modelName][$field['name'] . '_sec'];
				unset($this->params['data'][$modelName][$field['name'] . '_hour']);
				unset($this->params['data'][$modelName][$field['name'] . '_min']);
				unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
				$this->params['data'][$modelName][$field['name']] = $newDate;
				$this->data[$modelName][$field['name']] = $newDate;
			}
		}
	}
	
	
}
?>